/*
 * luaDefinitionBinding.cpp
 *
 *  Created on: Aug 28, 2013
 *      Author: jason
 */

#include "../../include/luaBindings.hpp"
#include "../../include/luaManager.hpp"
#include "../../include/Items/Items.hpp"
#include "../../include/Objects/Characters.hpp"
#include "../../include/Objects/Treasure.hpp"
#include "../../include/GlobalState.hpp"
#include "../../include/GameModes/ObjectManager.hpp"
#include "../../include/GameModes/Dialogue.hpp"
#include "../../include/GameModes/TownMode/TownMode.hpp"
#include "../../include/GameModes/TownMode/TriggerArea.hpp"

namespace LuaBindings {
struct enum_placeholder {};
// Lua Bindings for definitions
//  e.g. objects, enemies etc.
//  bindings for more complicated functions (like engine code) will be separated into other files.
void BindDefinitionCode() {
	luabind::module(LuaManager::Instance()->getLuaState())
	[
	 luabind::class_<GlobalState>("GlobalState")
////	 .def(luabind::constructor<>())
//	 .scope [
//	  .def("Instance", &GlobalState::Instance)
//	  ]
	 .def("addGold", &GlobalState::addGold)
	 .def("removeGold", &GlobalState::removeGold)
	 .def("getGold", &GlobalState::getGold)
	 .def("addCharacter", &GlobalState::addCharacter)
	 .def("setPreviousLocation", &GlobalState::setPreviousLocation)
	 .def("doesEventGroupExist", &GlobalState::doesEventGroupExist)
	 .def("doesEventExist", &GlobalState::doesEventExist)
	 .def("getEventValue", &GlobalState::getEventValue)
	 .def("setEventValue", &GlobalState::setEventValue)
	 ];
	luabind::object global_table = luabind::globals(LuaManager::Instance()->getLuaState());
	global_table["GlobalState"] = GlobalState::Instance();
	// Object bindings
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce")
	[
	 luabind::class_<OForce::Item>("Item")
	 .def(luabind::constructor<int>())
	 .def("getItemID", &OForce::Item::getItemID)
	 .def("getPrice", &OForce::Item::getPrice)
	 .def("getName", &OForce::Item::getName)
	 .def("setIcon", &OForce::Item::setIcon)
	 .def("setIconPosition", &OForce::Item::setIconPosition)
	 ];

	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Object")
	[
	 luabind::class_<OForce_Object::Object>("Object")
	 .def("getCollision", &OForce_Object::Object::getCollision)
	 .def("setCollision", &OForce_Object::Object::setCollision)
	 .def("getVisible", &OForce_Object::Object::getVisible)
	 .def("setVisible", &OForce_Object::Object::setVisible)
	 .def("getCurrentLayer", &OForce_Object::Object::getCurrentLayer)
	 .def("setCurrentLayer", &OForce_Object::Object::setCurrentLayer)
	 ];

	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Object")
	[
	 luabind::class_<OForce_Object::Character, OForce_Object::Object>("Character")
	 .def(luabind::constructor<float, float, float, float,std::string,
			 std::string, std::string, int, int>())
	 .def("updateFrame", &OForce_Object::Character::update)
	 .def("addDialogueByID", &OForce_Object::Character::addDialogueByID)
	 .def("draw", &OForce_Object::Character::draw)
	 .def("getNumAnimations", &OForce_Object::Character::getNumAnimations)
	 .def("setNumAnimations", &OForce_Object::Character::setNumAnimations)
	 .def("setAnimDuration", &OForce_Object::Character::setAnimDuration)
	 .def("addAnimFrames", &OForce_Object::Character::addAnimFrames)
	 .def("setVisible", &OForce_Object::Character::setVisible)
	 .def("setDirection", &OForce_Object::Character::setDirection)
	 .def("getXPosition", &OForce_Object::Character::getXPosition)
	 .def("getYPosition", &OForce_Object::Character::getYPosition)
	 .def("getCollide", &OForce_Object::Character::getCollide)
	 .def("setCollide", &OForce_Object::Character::setCollide)
	 .def("getCollisionArea", &OForce_Object::Character::getCollisionArea)
	 .def("setControlType", &OForce_Object::Character::setControlType)
	 .def("setMoveSpeed", &OForce_Object::Character::setMoveSpeed)
//	 .def("setCollisionRect", &Character::setCollisionRect)
	 ];

	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Object")
	[
	 luabind::class_<OForce_Object::Treasure, OForce_Object::Object>("Treasure")
	 .def(luabind::constructor<int, int, int, int, int, int, int>())
	 .def("Draw", &OForce_Object::Treasure::draw)
	 .def("Update", &OForce_Object::Treasure::update)
	 ];

	luabind::module(LuaManager::Instance()->getLuaState(), "OForce")
	[
	 luabind::class_<OForce::GenericItem>("GenericItem")
	 .def(luabind::constructor<int>())
	 ];

	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::ObjectManager>("ObjectManager")
	 .def(luabind::constructor<>())
	 .def("Update",&OForce_Mode::ObjectManager::update)
	 ];
/************************ EVENTS **********************************************/
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::LinkEvent>("LinkEvent")
	 .def(luabind::constructor<std::string, bool, float>())
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::TownEvent>("TownEvent")
//	 .def(luabind::constructor<std::string, int>())
	 .def("addEventAtStart", &OForce_Mode::TownEvent::addEventAtStart)
	 .def("addEventAtStartWithDelay", &OForce_Mode::TownEvent::addEventAtStartWithDelay)
	 .def("addEventAtEnd", &OForce_Mode::TownEvent::addEventAtEnd)
	 .def("addEventAtEndWithDelay", &OForce_Mode::TownEvent::addEventAtEndWithDelay)
//	 .def("update", &OForce_Mode::TownEvent::update)
//	 .def("start", &OForce_Mode::TownEvent::start)
	];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::CharacterEvent, OForce_Mode::TownEvent>("CharacterEvent")
	 .def("end", &OForce_Mode::CharacterEvent::end)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::ScriptedCharacterEvent, OForce_Mode::CharacterEvent>("ScriptedCharacterEvent")
	 .def(luabind::constructor<std::string, int, std::string, std::string>())
	 .def(luabind::constructor<std::string,
			 OForce_Object::Character *, std::string, std::string>())
	 .def("end", &OForce_Mode::ScriptedCharacterEvent::end)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::LookAtCharacterEvent, OForce_Mode::CharacterEvent>("LookAtCharacterEvent")
	 .def(luabind::constructor<std::string, int, int>())
	 .def(luabind::constructor<std::string,
			 OForce_Object::Character *, OForce_Object::Character *>())
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::MoveCharacterEvent, OForce_Mode::CharacterEvent>("MoveCharacterEvent")
	 .def(luabind::constructor<std::string, int, float, float>())
	 .def(luabind::constructor<std::string,
			 OForce_Object::Character *, float, float>())
	 .def("setDestination", &OForce_Mode::MoveCharacterEvent::setDestination)
	 .def("end", &OForce_Mode::MoveCharacterEvent::end)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::AnimateCharacterEvent, OForce_Mode::CharacterEvent>("AnimateCharacterEvent")
	 .def(luabind::constructor<std::string, int, std::string, float>())
	 .def(luabind::constructor<std::string,
			 OForce_Object::Character *, std::string, float>())
	 .def("end", &OForce_Mode::AnimateCharacterEvent::end)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::DialogueEvent, OForce_Mode::TownEvent>("DialogueEvent")
	 .def(luabind::constructor<std::string, int>())
	 .def(luabind::constructor<std::string, OForce_Mode::Dialogue *>())
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::SoundEvent, OForce_Mode::TownEvent>("SoundEvent")
	 .def(luabind::constructor<std::string, std::string>())
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::MapTransitionEvent, OForce_Mode::TownEvent>("MapTransitionEvent")
	 .def(luabind::constructor<std::string, std::string, std::string, bool>())
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::EventManager> ("EventManager")
	 .def(luabind::constructor<>())
	 .def("addEvent", &OForce_Mode::EventManager::addEvent)
	 .def("startEvent", (void(OForce_Mode::EventManager::*)(std::string))
	 			 &OForce_Mode::EventManager::startEvent)
	 .def("startEvent", (void(OForce_Mode::EventManager::*)(std::string, float))
			 &OForce_Mode::EventManager::startEvent)
//     .def("startEvent", (void(OForce_Mode::EventManager::*)(OForce_Mode::TownEvent))
//			 			 			 &OForce_Mode::EventManager::startEvent)
//	 .def("startEvent", (void(OForce_Mode::EventManager::*)(OForce_Mode::TownEvent, float))
//			 			 &OForce_Mode::EventManager::startEvent)
	 .def("pauseEvent", &OForce_Mode::EventManager::pauseEvent)
	 .def("resumeEvent", &OForce_Mode::EventManager::resumeEvent)
	 .def("pauseAllEvents", &OForce_Mode::EventManager::pauseAllEvents)
	 .def("resumeAllEvents", &OForce_Mode::EventManager::resumeAllEvents)
	 .def("endAllEvents", &OForce_Mode::EventManager::endAllEvents)
	 .def("end", (void(OForce_Mode::EventManager::*)(std::string, bool))
			 &OForce_Mode::EventManager::end)
	 ];
/********************************* DIALOGUE **********************************/
	luabind::module(LuaManager::Instance()->getLuaState(),"OForce_Mode")
	[
	 luabind::class_<OForce_Mode::DialogueManager> ("DialogueManager")
	 .def(luabind::constructor<>())
	 .def("addDialogue", &OForce_Mode::DialogueManager::addDialogue)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::Dialogue> ("Dialogue")
	 .def(luabind::constructor<int>())
	 .def("addLine", (void(OForce_Mode::Dialogue::*)(std::string, int))&OForce_Mode::Dialogue::addLine)
	 .def("addLine", (void(OForce_Mode::Dialogue::*)(std::string, int, int))&OForce_Mode::Dialogue::addLine)
	 ];
/***************************** Game State *************************************/
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::State>("State")
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::TownMode, OForce_Mode::State>("TownMode")
//	 .def(luabind::constructor<sf::RenderWindow*, std::string>())
	 .def(luabind::constructor<std::string>())
	 .def("update", &OForce_Mode::TownMode::update)
	 .def("draw", &OForce_Mode::TownMode::draw)
	 .def("addCharacter", &OForce_Mode::TownMode::addCharacter)
	 .def("setPlayerCharacter", &OForce_Mode::TownMode::setPlayerCharacter)
	 .def("setCamera", &OForce_Mode::TownMode::setCamera)
	 .def("addTreasure", &OForce_Mode::TownMode::addTreasure)
	 .def("addTriggerArea", &OForce_Mode::TownMode::addTriggerArea)
	 .def("playTrack", &OForce_Mode::TownMode::playTrack)
	 .def_readonly("getDialogueManager", &OForce_Mode::TownMode::getDialogueManager)
	 .def_readonly("getEventManager", &OForce_Mode::TownMode::getEventManager)
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "OForce_Mode")
	[
	 luabind::class_<OForce_Mode::TriggerArea>("TriggerArea")
	 .def(luabind::constructor<float, float, float, float>())
	 .def("isInArea", &OForce_Mode::TriggerArea::isInArea)
	 .def("enteredArea", &OForce_Mode::TriggerArea::enteredArea)
	 .def("update", &OForce_Mode::TriggerArea::update)
	 ];
/******************************** SFML ***************************************/
	luabind::module(LuaManager::Instance()->getLuaState(),"sf")
	[luabind::class_<sf::RenderWindow>("RenderWindow")
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "sf")
	[
	 luabind::class_<sf::Vector2f>("Vector2f")
	 ];
	luabind::module(LuaManager::Instance()->getLuaState(), "sf")
	[
	 luabind::class_<sf::FloatRect>("FloatRect")
	 ];
/******************************* ENUM *****************************************/
	luabind::module(LuaManager::Instance()->getLuaState())
	[
	 luabind::class_<enum_placeholder>("LBENUM")
	 .enum_("constants")
	 [
	  luabind::value("ALLY", OForce::ALLY),
	  luabind::value("ENEMY", OForce::ENEMY),
	  luabind::value("SELF", OForce::SELF)
	  ]
	 ];
//	luabind::module(LuaManager::Instance()->getLuaState(),"OForce_Object")
//	[
//	 luabind::class_<enum_placeholder>("LBENUM")
//	 .enum_("constants")
//	 [
//	  luabind::value("UP", OForce_Object::UP),
//	  luabind::value("DOWN",OForce_Object::DOWN),
//	  luabind::value("LEFT", OForce_Object::LEFT),
//	  luabind::value("RIGHT", OForce_Object::RIGHT)
//	  ]
//	 ];
//	luabind::module(LuaManager::Instance()->getLuaState(),"OForce_Object")
//	[
//	 luabind::class_<enum_placeholder>("LBENUM")
//	 .enum_("constants")
//	 [
//	  luabind::value("PLAYER", OForce_Object::PLAYER),
//	  luabind::value("STILL",OForce_Object::STILL),
//	  luabind::value("SCRIPTED", OForce_Object::SCRIPTED),
//	  luabind::value("RANDOMWALK", OForce_Object::RANDOM)
//	]
//	];
//	luabind::module(LuaManager::Instance()->getLuaState(),"OForce_Mode")
//	[
//	 luabind::class_<enum_placeholder>("LBENUM")
//	 .enum_("constants")
//	 [
//	  luabind::value("INVALID_EVENT", OForce_Mode::INVALID_EVENT),
//	  luabind::value("DIALOGUE_EVENT",OForce_Mode::DIALOGUE_EVENT),
//	  luabind::value("SCRIPTED_EVENT", OForce_Mode::SCRIPTED_EVENT),
//	  luabind::value("SCRIPTED_CHARACTER_EVENT", OForce_Mode::SCRIPTED_CHARACTER_EVENT),
//	  luabind::value("LOOK_AT_EVENT", OForce_Mode::LOOK_AT_EVENT),
//	  luabind::value("MOVE_EVENT", OForce_Mode::MOVE_EVENT),
//	  luabind::value("ANIMATE_EVENT", OForce_Mode::ANIMATE_EVENT),
//	  luabind::value("JOIN_PARTY_EVENT", OForce_Mode::JOIN_PARTY_EVENT),
//	  luabind::value("SOUND_EVENT", OForce_Mode::SOUND_EVENT),
//	  luabind::value("MAP_TRANSITION", OForce_Mode::MAP_TRANSITION),
//	  luabind::value("SHOP_EVENT", OForce_Mode::SHOP_EVENT),
//	  luabind::value("YES_NO_EVENT", OForce_Mode::YES_NO_EVENT)
//	  ]
//	 ];
//	luabind::object globalTable = luabind::globals(LuaManager::Instance()->getLuaState());
//	globalTable["GlobalState"] = GlobalState::Instance();
}

}


